﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows.Data;
using System.Windows.Markup;


namespace SmartGrid.NET.WPFUtils.Converters
{
    /// <summary>
    /// http://drwpf.com/blog/2009/03/17/tips-and-tricks-making-value-converters-more-accessible-in-markup/
    /// 
    ///     conventional
    ///     <Window.Resources>
    ///         <src:MyConverter x:Key="MyConverter" />
    ///     </Window.Resources> 
    ///     And then later the converter must be specified using a StaticResource reference, which incurs some overhead (albeit small overhead, in the grand scheme of things) for the resource resolution:
    ///     <TextBlock Text="{Binding SomePath, Converter={StaticResource MyConverter}}" />
    ///
    ///     new
    ///     <TextBlock Text="{Binding SomePath, Converter={src:DummyConverter}}" />
    /// 
    /// 
    /// 
    /// ditto for commands: http://www.hardcodet.net/2009/04/wpf-command-markup-extension
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class ConverterBase<T> :
        MarkupExtension,
        IValueConverter
        where T : class, new()
    {
        protected static T _Converter = null;

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (_Converter == null)
            {
                _Converter = new T();
            }

            return _Converter;
        }

        #region IValueConverter Members

        protected virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return Convert(value, targetType, parameter, culture);
        }

        protected virtual object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return ConvertBack(value, targetType, parameter, culture);
        }

        #endregion
    }


    public class ConverterBase2<T> :
        MarkupExtension,
        IValueConverter
        where T : class, IValueConverter, new()
    {
        protected static IValueConverter _Converter = null;

        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (_Converter == null)
            {
                _Converter = new T();
            }

            return _Converter;
        }

        #region IValueConverter Members

        protected virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return _Converter.Convert(value, targetType, parameter, culture);
        }

        protected virtual object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotSupportedException();
        }
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return _Converter.ConvertBack(value, targetType, parameter, culture);
        }

        #endregion
    }



    //Sample derived class
    public class BytesToKBValueConverter : ConverterBase<BytesToKBValueConverter>
    {
        protected override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value != null && value is double)
            {
                double bytes = System.Convert.ToDouble(value);
                return bytes / 1024.0d;
            }
            else
                return value;
        }
    }

    public class BytesToKBValueConverter2 : ConverterBase2<BytesToKBValueConverter2>
    {
        protected override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value != null && value is double)
            {
                double bytes = System.Convert.ToDouble(value);
                return bytes / 1024.0d;
            }
            else
                return value;
        }
    }
}
